package services

import (
	"errors"
	"fmt"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"

	"github.com/inntu/backend/api/models"
	"github.com/inntu/backend/config"
)

// PageService 页面服务
type PageService struct {
	db *gorm.DB
}

// NewPageService 创建页面服务实例
func NewPageService() *PageService {
	return &PageService{
		db: config.GetGormDB(),
	}
}

// GetPages 获取所有页面列表
func (s *PageService) GetPages(c *gin.Context) ([]models.Page, error) {
	var pages []models.Page

	// 构建查询
	query := s.db.Where("status = ?", 1)

	// 执行查询
	result := query.Order("id ASC").Find(&pages)
	if result.Error != nil {
		return nil, fmt.Errorf("查询页面列表失败: %v", result.Error)
	}

	return pages, nil
}

// GetPageByID 根据ID获取页面详情
func (s *PageService) GetPageByID(c *gin.Context, id int) (*models.Page, error) {
	var page models.Page

	result := s.db.Where("id = ? AND status = ?", id, 1).First(&page)
	if result.Error != nil {
		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
			return nil, fmt.Errorf("页面不存在")
		}
		return nil, fmt.Errorf("查询页面详情失败: %v", result.Error)
	}

	return &page, nil
}

// GetPageByCode 根据代码获取页面详情
func (s *PageService) GetPageByCode(c *gin.Context, code string) (*models.Page, error) {
	var page models.Page

	result := s.db.Where("code = ? AND status = ?", code, 1).First(&page)
	if result.Error != nil {
		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
			return nil, fmt.Errorf("页面不存在")
		}
		return nil, fmt.Errorf("查询页面详情失败: %v", result.Error)
	}

	return &page, nil
}

// GetPageWithCategories 获取页面及其分类
func (s *PageService) GetPageWithCategories(c *gin.Context, pageCode string) (*models.Page, error) {
	var page models.Page

	// 查询页面及其关联的分类
	result := s.db.Preload("Categories", func(db *gorm.DB) *gorm.DB {
		return db.Where("status = ?", 1).Order("id ASC")
	}).Where("code = ? AND status = ?", pageCode, 1).First(&page)

	if result.Error != nil {
		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
			return nil, fmt.Errorf("页面不存在")
		}
		return nil, fmt.Errorf("查询页面及分类失败: %v", result.Error)
	}

	return &page, nil
}

// GetPageWithCategoriesAndItems 获取页面及其分类和项目的完整结构
func (s *PageService) GetPageWithCategoriesAndItems(c *gin.Context, pageCode string) (*models.Page, error) {
	var page models.Page

	// 查询页面及其关联的分类和项目
	result := s.db.Preload("Categories", func(db *gorm.DB) *gorm.DB {
		return db.Where("status = ?", 1).Order("id ASC")
	}).Preload("Categories.Items", func(db *gorm.DB) *gorm.DB {
		return db.Where("status = ?", 1).Order("id ASC")
	}).Where("code = ? AND status = ?", pageCode, 1).First(&page)

	if result.Error != nil {
		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
			return nil, fmt.Errorf("页面不存在")
		}
		return nil, fmt.Errorf("查询页面及分类项目失败: %v", result.Error)
	}

	return &page, nil
}

// CreatePage 创建页面
func (s *PageService) CreatePage(page *models.Page) error {
	// 检查代码是否已存在
	var count int64
	s.db.Model(&models.Page{}).Where("code = ?", page.Code).Count(&count)
	if count > 0 {
		return fmt.Errorf("页面代码已存在")
	}

	result := s.db.Create(page)
	if result.Error != nil {
		return fmt.Errorf("创建页面失败: %v", result.Error)
	}

	return nil
}

// UpdatePage 更新页面
func (s *PageService) UpdatePage(page *models.Page) error {
	id := page.ID
	// 检查页面是否存在
	var existingPage models.Page
	result := s.db.Where("id = ?", id).First(&existingPage)
	if result.Error != nil {
		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
			return fmt.Errorf("页面不存在")
		}
		return fmt.Errorf("查询页面失败: %v", result.Error)
	}

	// 检查代码是否与其他页面冲突
	var count int64
	s.db.Model(&models.Page{}).Where("code = ? AND id != ?", page.Code, id).Count(&count)
	if count > 0 {
		return fmt.Errorf("页面代码已存在")
	}

	// 开始事务处理页面更新和分类关系
	tx := s.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 更新页面基本信息
	result = tx.Model(&existingPage).Updates(map[string]interface{}{
		"code":          page.Code,
		"name":          page.Name,
		"description":   page.Description,
		"display_order": page.DisplayOrder,
		"status":        page.Status,
	})
	if result.Error != nil {
		tx.Rollback()
		return fmt.Errorf("更新页面失败: %v", result.Error)
	}

	// 如果传入了分类关系，则更新分类关系
	if page.Categories != nil {
		// 先删除现有的分类关系
		if err := tx.Exec("DELETE FROM page_categories WHERE page_id = ?", id).Error; err != nil {
			tx.Rollback()
			return fmt.Errorf("删除现有分类关系失败: %v", err)
		}

		// 添加新的分类关系
		for _, category := range page.Categories {
			if err := tx.Exec("INSERT INTO page_categories (page_id, category_id, status) VALUES (?, ?, 1)", id, category.ID).Error; err != nil {
				tx.Rollback()
				return fmt.Errorf("添加分类关系失败: %v", err)
			}
		}
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		return fmt.Errorf("提交事务失败: %v", err)
	}

	return nil
}

// DeletePage 删除页面（软删除）
func (s *PageService) DeletePage(id int) error {
	// 检查页面是否存在
	var page models.Page
	result := s.db.Where("id = ?", id).First(&page)
	if result.Error != nil {
		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
			return fmt.Errorf("页面不存在")
		}
		return fmt.Errorf("查询页面失败: %v", result.Error)
	}

	// 软删除页面
	result = s.db.Delete(&page)
	if result.Error != nil {
		return fmt.Errorf("删除页面失败: %v", result.Error)
	}

	return nil
}

// AddCategoryToPage 添加分类到页面
func (s *PageService) AddCategoryToPage(c *gin.Context, pageID, categoryID int) error {
	// 检查页面和分类是否存在
	var page models.Page
	var category models.Category

	if err := s.db.Where("id = ? AND status = ?", pageID, 1).First(&page).Error; err != nil {
		return fmt.Errorf("页面不存在")
	}

	if err := s.db.Where("id = ? AND status = ?", categoryID, 1).First(&category).Error; err != nil {
		return fmt.Errorf("分类不存在")
	}

	// 检查关系是否已存在
	var count int64
	s.db.Table("page_categories").Where("page_id = ? AND category_id = ?", pageID, categoryID).Count(&count)
	if count > 0 {
		return fmt.Errorf("该分类已经关联到此页面")
	}

	// 添加关联关系
	result := s.db.Exec("INSERT INTO page_categories (page_id, category_id) VALUES (?, ?)", pageID, categoryID)
	if result.Error != nil {
		return fmt.Errorf("添加分类到页面失败: %v", result.Error)
	}

	return nil
}

// RemoveCategoryFromPage 从页面移除分类
func (s *PageService) RemoveCategoryFromPage(c *gin.Context, pageID, categoryID int) error {
	// 删除关联关系
	result := s.db.Exec("DELETE FROM page_categories WHERE page_id = ? AND category_id = ?", pageID, categoryID)
	if result.Error != nil {
		return fmt.Errorf("从页面移除分类失败: %v", result.Error)
	}

	return nil
}

// GetHierarchyData 获取完整的层级数据（页面->分类->项目->关联项目）
func (s *PageService) GetHierarchyData(c *gin.Context) ([]models.Page, error) {
	var pages []models.Page

	// 一次性查询所有页面及其关联的分类和项目，包括page类型项目的关联项目
	result := s.db.Preload("Categories", func(db *gorm.DB) *gorm.DB {
		return db.Where("status = ?", 1).Order("id ASC")
	}).Preload("Categories.Items", func(db *gorm.DB) *gorm.DB {
		return db.Where("status = ?", 1).Order("id ASC")
	}).Preload("Categories.Items.RelatedItems", func(db *gorm.DB) *gorm.DB {
		// 只为content_type为page的项目预加载关联项目
		return db.Joins("JOIN page_items ON page_items.item_id = items.id").Where("items.status = ?", 1).Order("page_items.display_order ASC, items.id ASC")
	}).Where("status = ?", 1).Order("id ASC").Find(&pages)

	if result.Error != nil {
		return nil, fmt.Errorf("查询层级数据失败: %v", result.Error)
	}

	return pages, nil
}

// GetAvailableCategories 获取可用的分类列表（用于关系管理）
func (s *PageService) GetAvailableCategories(c *gin.Context) ([]models.Category, error) {
	var categories []models.Category
	result := s.db.Where("status = ?", 1).Order("id ASC").Find(&categories)
	if result.Error != nil {
		return nil, fmt.Errorf("查询分类列表失败: %v", result.Error)
	}
	return categories, nil
}

// GetAvailableItems 获取可用的项目列表（用于关系管理）
func (s *PageService) GetAvailableItems(c *gin.Context) ([]models.Item, error) {
	var items []models.Item
	result := s.db.Where("status = ?", 1).Order("id ASC").Find(&items)
	if result.Error != nil {
		return nil, fmt.Errorf("查询项目列表失败: %v", result.Error)
	}
	return items, nil
}
